﻿using System.Text.Json;
using Core.Domain.Contracts;
using Core;
using Core.Extensions;

namespace Core.Domain.ValueObjects;

/// <summary>
/// 用户偏好项（值对象）
/// 支持任意类型、JSON 存储、可被 EF Core 序列化
/// </summary>
public class UserPreference : ValueObject
{
    /// <summary> 
    /// 唯一键（标识偏好项） 
    /// </summary>
    public string Key { get; private set; } = default!;

    /// <summary> 
    /// JSON 格式存储的值 
    /// </summary>
    public string Value { get; private set; } = default!;

    /// <summary> 
    /// 可选：偏好项的类型名称（用于调试或后续扩展）
    /// </summary>
    public string? ValueType { get; private set; }

    /// <summary> 
    /// 可选：说明或描述 
    /// </summary>
    public string? Description { get; private set; }

    private UserPreference() { } // EF Core 使用

    private UserPreference(string key, string value, string? valueType = null, string? description = null)
    {
        Key = key;
        Value = value;
        ValueType = valueType;
        Description = description;
    }

    /// <summary>
    /// 创建偏好项（自动序列化）
    /// </summary>
    public static UserPreference Create<T>(string key, T value, string? description = null)
    {
        if (string.IsNullOrWhiteSpace(key))
            throw new BoilerplateException("偏好项 Key 不能为空");

        var json = JsonSerializer.Serialize(value);
        return new UserPreference(key, json, typeof(T).FullName, description);
    }

    /// <summary>
    /// 获取偏好值（自动反序列化）
    /// </summary>
    public T GetValue<T>()
    {
        if (string.IsNullOrWhiteSpace(Value))
            return default!;

        try
        {
            var trimmed = Value.Trim('"');

            if (bool.TryParse(trimmed, out var boolResult))
                return (T)(object)boolResult;

            if (int.TryParse(trimmed, out var intResult))
                return (T)(object)intResult;

            if (double.TryParse(trimmed, out var doubleResult))
                return (T)(object)doubleResult;

            if (!trimmed.IsJson())
                return (T)(object)trimmed;

            return JsonSerializer.Deserialize<T>(Value) ?? default!;
        }
        catch (Exception ex)
        {
            throw new BoilerplateException($"无法将偏好项 [{Key}] 的值解析为类型 {typeof(T).Name}", ex);
        }
    }

    /// <summary>
    /// 校验键合法性（可扩展到 Key 白名单）
    /// </summary>
    public void Validate()
    {
        if (string.IsNullOrWhiteSpace(Key))
            throw new BoilerplateException("偏好项 Key 不能为空");

        if (Key.Length > 100)
            throw new BoilerplateException("偏好项 Key 过长");
    }

    protected override IEnumerable<object?> GetEqualityComponents()
    {
        yield return Key;
        yield return Value;
    }

    public override string ToString() => $"{Key} = {Value}";
}
